import BD from '../baseData'
import { tools } from '@jiess/utils'
const { isUndef, sourceCopy, identify } = tools

const getI18n = function(label, config) {
	const i18nConfig = Object.assign({}, this.rootNode.config, config);
	const { i18nPathOption, i18nIgnoreOption } = i18nConfig;
	if (isUndef(label)) {
		return ''
	} else if (config && i18nPathOption && !i18nIgnoreOption) {
		return this.VNode.$mapping.J_i18n(label, label, i18nPathOption)
	} else {
		return label
	}
}

const getItem = function(label, disabled, { is, value, ...other }, { bind } = {}, changeOption) {
	const result = { ...other, ...bind };
	result.label = getI18n.call(this, label, changeOption)
	result.disabled = disabled
	if (!isUndef(is)) result.is = is
	if (!isUndef(value)) result.value = value
	return result
}
const getOther = function(component) {
	return {
		//去除组件的label属性
		needLabelField: true,
		//组件外层不需要嵌套form-item
		noLabel: true,
		//父节点
		parentNode: component
	}
}
//填充父容器宽度
const fillWidth = function(other) {
	return Object.assign({ buildStyle: { 'flex-grow': 1 } }, other)
}
const renderNode = function(item, field = "renderOption") {
	const render = item[field]
	if (identify(render, 'function')) {
		const result = render()
		return Array.isArray(result) ? result : [result]
	}
}
const renderChildren = function(item, label, field = "renderGroup") {
	const result = renderNode(item, field)
	if (!result) return [this.jsRender(h => h('span', getI18n.call(this, label, item)))]
	return result
}
export default {
	//设定单选框组
	getGroupRadio(component, groups, changeOption = {}) {
		const { value = 'value', label = 'label', size = 'size', disabled = 'disabled' } = changeOption;
		return groups.map(item => {
			//==========此处遵照惯例和elementUI是反的============
			const radioComponent = this.jsChildren(
				getItem.call(this, item[value], item[disabled], {
					is: 'radio',
					size: item[size],
				}, item),
				renderChildren.call(this, item, item[label]), getOther(component))
			return radioComponent
		})
	},
	//设定复选框组
	getGroupCheckbox(component, groups, changeOption = {}) {
		const { value = 'value', label = 'label', size = 'size', disabled = 'disabled' } = changeOption;
		//==========此处遵照惯例和elementUI是反的============
		return groups.map(item => {
			const checkComponent = this.jsChildren(
				getItem.call(this, item[value], item[disabled], {
					is: changeOption.is || 'checkbox',
					size: item[size],
				}, item),
				renderChildren.call(this, item, item[label]), getOther(component))
			return checkComponent
		})
	},
	//下拉分组选择器的用法
	getGroupOption(component, groups, changeOptionGroup = {}, changeOption = {}) {
		const { options = 'options', label = 'label', disabled = 'disabled' } = changeOptionGroup;
		return groups.map(item => {
			const groupComponent = this.jsChildren(
				getItem.call(this, item[label], item[disabled], {
					is: 'optionGroup',
					forceNest: true
				}, item, changeOption),
				this.getOption(groupComponent, item[options], changeOption, []), getOther(component))
			return groupComponent
		})
	},
	//获取下拉选择的组件对象
	getOption(component, options = [], changeOption = {}, initChildren = []) {
		const { value = 'value', label = 'label', disabled = 'disabled', model = 'field' } = changeOption;
		return sourceCopy(initChildren).concat(options).map(item => this.jsChildren(
			getItem.call(this, item[label], item[disabled], {
				is: 'option',
				forceNest: true,
				allowAddName: false,
				value: model === 'object' ? item : item[value]
			}, item, changeOption), renderNode(item), getOther(component)))
	},
	//级联选择器的配置
	recursiveOptions(data, changeOption = {}) {
		const { value = 'value', label = 'label', children = 'children', disabled = 'disabled' } = changeOption;
		const childrens = []
		if (Array.isArray(data)) {
			for (let item of data) {
				const param = getItem.call(this, item[label], item[disabled], {
					value: item[value]
				}, undefined, changeOption)
				//可以单独控制child是否存在 即是否有子层级
				const arr = item[children]
				if (Array.isArray(arr)) {
					childrens.push(Object.assign(param, {
						children: this.recursiveOptions(arr, changeOption)
					}))
				} else {
					childrens.push(param)
				}
			}
		}
		return childrens
	},
	// ==========================华丽的分割线==================================
	jsInput(param, children, other = {}) {
		param.is = 'input'
		return this.jsComponent(param, children, fillWidth(other))
	},
	/*************************************************************************
	 * 联想输入框
	 *************************************************************************/
	jsAutocomplete(param, children, other = {}) {
		param.is = 'autocomplete'
		//在iview中，该组件的value值不能定义为null
		if (!Reflect.has(param, 'initValue')) param.initValue = ''
		return this.jsComponent(param, children, fillWidth(other))
	},
	/*************************************************************************
	 * 下拉框及其分组
	 *************************************************************************/
	jsSelect(param, children, other = {}) {
		param.is = 'select'
		param.forceNest = true
		// initChildren 初始化时最初的选项值,如需要控制默认的请选择
		// changeOption 设定optionss中的字段的映射关系
		const { options, initChildren, changeOption } = param;
		return this.jsComponent(param, children, {
			buildComponentCallback: component => {
				//构造el-option子组件，特点：不需要setInit操作
				if (Array.isArray(options)) {
					//直接赋值
					component.node = this.getOption(component, options, changeOption, initChildren)
				} else if (identify(options, 'promise')) {
					//异步回调
					options.then(datas => {
						component.node = this.getOption(component, datas, changeOption,
							initChildren)
					})
				} else if (identify(options, 'string')) {
					//从BD.json中取值
					component.node = this.getOption(component, BD[options], changeOption, initChildren)
				}
			},
			...fillWidth(other)
		});
	},
	jsSelectGroup(param, children, other = {}) {
		param.is = 'select'
		param.forceNest = true
		// changeOptionGroup 设定group中的字段的映射关系
		const { groups, initChildren, changeOption, changeOptionGroup } = param;
		return this.jsComponent(param, children, {
			buildComponentCallback: component => {
				//构造el-option子组件，特点：不需要setInit操作
				if (Array.isArray(groups)) {
					//直接赋值
					component.node = this.getGroupOption(component, groups, changeOptionGroup, changeOption,
						initChildren)
				} else if (identify(groups, 'promise')) {
					//异步回调
					groups.then(datas => {
						component.node = this.getGroupOption(component, datas, changeOptionGroup,
							changeOption, initChildren)
					})
				} else if (identify(groups, 'string')) {
					//从BD.json中取值
					component.node = this.getGroupOption(component, BD[groups], changeOptionGroup,
						changeOption,
						initChildren)
				}
			},
			...fillWidth(other)
		});
	},
	/*************************************************************************
	 * 单选框及其分组
	 *************************************************************************/
	jsRadio(param, children, other = {}) {
		param.is = 'radio'
		return this.jsComponent(param, children, other);
	},
	jsRadioGroup(param, children, other = {}) {
		param.is = 'radioGroup'
		const { groups, changeOption } = param;
		return this.jsComponent(param, children, {
			buildComponentCallback: component => {
				if (Array.isArray(groups)) {
					//直接赋值
					component.node = this.getGroupRadio(component, groups, changeOption)
				} else if (identify(groups, 'promise')) {
					//异步回调
					groups.then(datas => {
						component.node = this.getGroupRadio(component, datas, changeOption)
					})
				} else if (identify(groups, 'string')) {
					//从BD.json中取值
					component.node = this.getGroupRadio(component, BD[groups], changeOption)
				}
			},
			...other
		});
	},
	/*************************************************************************
	 * 复选框及其分组
	 *************************************************************************/
	jsCheckbox(param, children, other = {}) {
		param.is = 'checkbox'
		return this.jsComponent(param, children, other);
	},
	jsCheckboxButton(param, children, other = {}) {
		param.is = 'checkboxButton'
		return this.jsComponent(param, children, other);
	},
	jsCheckboxGroup(param, children, other = {}) {
		param.is = 'checkboxGroup'
		const { groups, changeOption } = param;
		//需要默认赋值为空数组
		if (!Reflect.has(param, 'initValue')) param.initValue = []
		return this.jsComponent(param, children, {
			buildComponentCallback: component => {
				if (Array.isArray(groups)) {
					//直接赋值
					component.node = this.getGroupCheckbox(component, groups, changeOption)
				} else if (identify(groups, 'promise')) {
					//异步回调
					groups.then(datas => {
						component.node = this.getGroupCheckbox(component, datas, changeOption)
					})
				} else if (identify(groups, 'string')) {
					//从BD.json中取值
					component.node = this.getGroupCheckbox(component, BD[groups], changeOption)
				}
			},
			...other
		});
	},
	/*************************************************************************
	 * 级联选择器
	 *************************************************************************/
	jsCascader(param, children, other) {
		param.is = 'cascader'
		if (!Reflect.has(param, 'initValue')) param.initValue = []
		const fields = { 'element': 'options', 'iview': 'data' };
		const optionsField = fields[this.VNode.ui];
		const optionsData = param[optionsField];

		return this.jsComponent(param, children, {
			buildParamCallback: () => {
				if (Array.isArray(optionsData)) {
					//直接赋值
					param[optionsField] = this.recursiveOptions(optionsData, param.changeOption)
				} else if (identify(optionsData, 'promise')) {
					param[optionsField] = []
					const buildParam = this.parentNode.form.buildParam
					//异步回调
					optionsData.then(datas => {
						const proxyItem = buildParam.items[param.name]
						if (proxyItem) proxyItem[optionsField] = this.recursiveOptions(datas, param
							.changeOption)
					})
				} else if (identify(optionsData, 'string')) {
					//从BD中取值
					param[optionsField] = this.recursiveOptions(BD[optionsData], param.changeOption)
				}
			},
			...fillWidth(other)
		})
	},

	/*************************************************************************
	 * 时间选择器
	 *************************************************************************/
	jsTime(param, children, other = {}) {
		param.is = 'timePicker'
		return this.jsComponent(param, children, fillWidth(other))
	},
	/*************************************************************************
	 * 时间范围选择器，可被jsTime替代
	 *************************************************************************/
	jsTimeRange(param, children, other = {}) {
		param.is = 'timePicker'
		if (this.VNode.ui === 'element') {
			param['is-range'] = true
		} else {
			param.type = 'timerange'
		}
		return this.jsComponent(param, children, fillWidth(other))
	},
	/*************************************************************************
	 * 带有阶梯的时间选择
	 *************************************************************************/
	jsTimeSelect(param, children, other = {}) {
		param.is = 'timeSelect'
		return this.jsComponent(param, children, fillWidth(other))
	},
	/*************************************************************************
	 * 日期选择器
	 *************************************************************************/
	jsDate(param, children, other = {}) {
		param.is = 'datePicker'
		return this.jsComponent(param, children, fillWidth(other))
	},

	/*************************************************************************
	 * 计数器
	 *************************************************************************/
	jsInputNumber(param, children, other = {}) {
		param.is = 'inputNumber'
		return this.jsComponent(param, children, fillWidth(other))
	},
	/*************************************************************************
	 * 开关
	 *************************************************************************/
	jsSwitch(param, children, other = {}) {
		param.is = 'switch'
		//由于存在扩展value
		if (!Reflect.has(param, 'initValue')) param.initValue = false
		return this.jsComponent(param, children, other);
	},
	/*************************************************************************
	 * 按钮
	 *************************************************************************/
	jsButton(param, children, other) {
		param.is = 'button'
		return this.jsChildren(param, children, other)
	}
}
